/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.deployment.manager;

import br.com.deployment.entidade.localidade.Cidade;
import br.com.deployment.entidade.registroimovel.AreaInterpi;
import br.com.deployment.entidade.registroimovel.GeoRef;
import br.com.deployment.servico.AreaInterpiServico;
import br.com.deployment.servico.CidadeServico;
import br.com.deployment.servico.MapServico;
import br.com.deployment.util.ViewMapInterpi;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.event.map.OverlaySelectEvent;
import org.primefaces.event.map.StateChangeEvent;
import org.primefaces.model.map.*;

/**
 *
 * @author roniere
 */
@ManagedBean
@ViewScoped
public class ManagerVerStateCoord implements Serializable {

    @EJB
    CidadeServico cidadeServico;
    @EJB
    MapServico mapServico;
    @EJB
    AreaInterpiServico areaInterpiServico;
    private MapModel polygonModel;
    private String zoomMap;
    private String centerMap;
    private List<GeoRef> lstGeoRef;
    private Marker marker;
    private List<String> lstCorAux;
    private List<ViewMapInterpi> lstViewMapInterpi;

    @PostConstruct
    public void init() {
        this.polygonModel = new DefaultMapModel();
        this.centerMap = "-2.9136, -41.7577";
        this.zoomMap = "4";
        this.lstCorAux = new ArrayList<String>();
        this.lstViewMapInterpi = new ArrayList<ViewMapInterpi>();
        initInterpi(null);
        initCidade(null);
    }
    
   

    public MapModel getPolygonModel() {
        return polygonModel;
    }

    public void setPolygonModel(MapModel polygonModel) {
        this.polygonModel = polygonModel;
    }

    public String getCenterMap() {
        return centerMap;
    }

    public void setCenterMap(String centerMap) {
        this.centerMap = centerMap;
    }

    public List<GeoRef> getLstGeoRef() {
        return lstGeoRef;
    }

    public void setLstGeoRef(List<GeoRef> lstGeoRef) {
        this.lstGeoRef = lstGeoRef;
    }

    public List<ViewMapInterpi> getLstViewMapInterpi() {
        return lstViewMapInterpi;
    }

    public void setLstViewMapInterpi(List<ViewMapInterpi> lstViewMapInterpi) {
        this.lstViewMapInterpi = lstViewMapInterpi;
    }
    

    public String getZoomMap() {
        return zoomMap;
    }

    public void setZoomMap(String zoomMap) {
        this.zoomMap = zoomMap;
    }

    public Marker getMarker() {
        return marker;
    }

    public void setMarker(Marker marker) {
        this.marker = marker;
    }
    
     public void onStateChange(StateChangeEvent event) {  
        LatLngBounds bounds = event.getBounds();  
        int zoomLevel = event.getZoomLevel();  
        this.zoomMap = String.valueOf(zoomLevel);
        this.centerMap = event.getCenter().toString();
        System.err.println( " "+zoomMap + " " + centerMap);
    }  
    
    public void remove(Polygon p, Polyline p1, Marker m){
        if(polygonModel.getPolygons().contains(p)){
            polygonModel.getPolygons().remove(p);
        }else{
            polygonModel.getPolygons().add(p);
        }
        if(polygonModel.getPolylines().contains(p1)){
            polygonModel.getPolylines().remove(p1);
        }else{
            polygonModel.getPolylines().add(p1);
        }
        if(polygonModel.getMarkers().contains(m)){
            polygonModel.getMarkers().remove(m);
        }else{
            polygonModel.getMarkers().add(m);
        }
         System.err.println( "");
    }

    public void initInterpi(List<GeoRef> g) {
        for (AreaInterpi areaInterpi : areaInterpiServico.findAll()) {
            lstGeoRef = (mapServico.getGeoRef(AreaInterpi.class, areaInterpi.getId()));
            if(g != null){
                if(!lstGeoRef.contains(g)){
                    initMapInterpi(areaInterpi);
                }
            }else{
                initMapInterpi(areaInterpi);
            }
        }
    }

    public void initCidade(List<GeoRef> g) {
        
        for (Cidade cidade : cidadeServico.cidadesCoord()) {
            lstGeoRef = (mapServico.getGeoRef(Cidade.class, cidade.getCod_cidade()));
            if(g != null){
                if(!lstGeoRef.contains(g)){
                    initMap(cidade);
                }
            }else{
                initMap(cidade);
            }
            
        }
    }

    private String getColor() {
        List<String> lstCor = new ArrayList<String>();
        lstCor.add("#FF9900");
        lstCor.add("#2288AA");
        lstCor.add("#8F49FF");
        lstCor.add("#004B84");
        lstCor.add("#FEFF49");
        lstCor.add("#A5FFFF");
        lstCor.add("#A7F477");
        lstCor.add("#7db9e8");
        lstCor.add("#8FAAB5");
        lstCor.add("#3B5998");
        lstCor.add("#00BFFF");
        lstCor.add("#98FB98");
        lstCor.add("#FFFF00");
        lstCor.add("#D8BFD8");
        lstCor.add("#F0FFFF");
        lstCor.add("#DAA520");
        lstCor.add("#FF4040");
        lstCor.add("#AB82FF");
        lstCor.add("#90EE90");
        lstCor.add("#2E8B57");
        lstCor.add("#FF4020");
        lstCor.add("#AB82AF");
        lstCor.add("#90EE60");
        lstCor.add("#2E8B27");

        lstCor.add("http://maps.google.com/mapfiles/ms/micons/blue-dot.png");
        lstCor.add("http://maps.google.com/mapfiles/ms/micons/pink-dot.png");
        lstCor.add("http://maps.google.com/mapfiles/ms/micons/yellow-dot.png");

        String cor = lstCor.get(new Random().nextInt(24));
        
        return cor;
    }
    
    public boolean existCor(String cor){
         if(!lstCorAux.contains(cor)){
            lstCorAux.add(cor);
            return false;
         }
         return true;
    }

    public void initMapInterpi(AreaInterpi areaInterpi) {
        
        
        if (lstGeoRef.size() >= 1) {
            Polygon polygon = new Polygon();

            Double centerX = 0D;
            Double centerY = 0D;
            int tam = lstGeoRef.size();
            Polyline polyline = new Polyline();
            for (GeoRef geoRef : lstGeoRef) {
                
                if (geoRef.getLat() != 0.0 && geoRef.getLng() != 0.0) {
                    polyline.getPaths().add(new LatLng(geoRef.getLat(), geoRef.getLng()));
                    polygon.getPaths().add(new LatLng(geoRef.getLat(), geoRef.getLng()));
                    centerX += geoRef.getLat() / tam;
                    centerY += geoRef.getLng() / tam;
                }

            }
            System.err.println("INTERPI "+areaInterpi.getId());
            
            Marker m = new Marker(new LatLng(centerX, centerY), "Área Interpi " + areaInterpi.getId(),
                           areaInterpi.getDescricao() + " "
                           + (polygon.getPaths().size() >= 3 ? "<br /> <b>Área calculada pelo Sistema: </b>" + calcArea(polygon) + " ha <br />" : ""), "http://maps.google.com/mapfiles/ms/micons/red-dot.png");
            polygonModel.addOverlay(m);

            polygon.setStrokeColor("#000000");
            polygon.setFillColor(getColor());
            polygon.setStrokeOpacity(0.8);
            polygon.setFillOpacity(0.2);


            lstViewMapInterpi.add(new ViewMapInterpi(areaInterpi.getDescricao(), true, polygon, polyline, m));
            
            polygonModel.addOverlay(polygon);
            polygonModel.addOverlay(polyline);

            for (Marker marker : polygonModel.getMarkers()) {
                marker.setDraggable(true);
            }
        }
    }

    public void initMap(Cidade cidade) {
       
        if (lstGeoRef.size() >= 1) {
            Polygon polygon = new Polygon();

            Double centerX = 0D;
            Double centerY = 0D;
            int tam = lstGeoRef.size();
            Polyline polyline = new Polyline();
            for (GeoRef geoRef : lstGeoRef) {
                if (geoRef.getLat() != 0.0 && geoRef.getLng() != 0.0) {
                    polyline.getPaths().add(new LatLng(geoRef.getLat(), geoRef.getLng()));
                    polygon.getPaths().add(new LatLng(geoRef.getLat(), geoRef.getLng()));
                    centerX += geoRef.getLat() / tam;
                    centerY += geoRef.getLng() / tam;
                }

            }
            Marker m = new Marker(new LatLng(centerX, centerY),
                           "Município: " + cidade.getNom_cidade(), "Estado: " + cidade.getCod_estado().getNom_estado(),
                           "http://maps.google.com/mapfiles/ms/micons/blue-dot.png");
            
            polygonModel.addOverlay(m);

            polygon.setStrokeColor("#FF9900");
            polygon.setFillColor("#FF9900");
            polygon.setStrokeOpacity(0.2);
            polygon.setFillOpacity(0.2);

            if (polygon.getPaths().size() >= 3) {
//                System.err.println("Município");
//                calcArea(polygon);
            }

            lstViewMapInterpi.add(new ViewMapInterpi(cidade.getNom_cidade(), true, polygon, polyline, m));
            polygonModel.addOverlay(polygon);
            polygonModel.addOverlay(polyline);

            for (Marker marker : polygonModel.getMarkers()) {
                marker.setDraggable(true);
            }
        }
    }

    public double calcArea(Polygon pl) {

        WKTReader reader = new WKTReader(new GeometryFactory());

        String p = "POLYGON(( ";
        for (LatLng ll : pl.getPaths()) {
            p += ll.getLat() + " " + ll.getLng() + ", ";
        }
        p += "" + pl.getPaths().get(0).getLat() + " " + pl.getPaths().get(0).getLng() + " )) ";

        com.vividsolutions.jts.geom.Polygon polygonInt = null;
        try {
            polygonInt = (com.vividsolutions.jts.geom.Polygon) reader.read(p);
            System.err.println(" --------------INTERPI-------------------- ");
            System.err.println("Area: " + polygonInt.getArea());
            System.err.println("Perímetro: " + polygonInt.getLength());
            System.err.println("Boundary: " + polygonInt.getBoundary());
            System.err.println("Dimension: " + polygonInt.getDimension());
            System.err.println(" ---------------------------------- ");
        } catch (ParseException ex) {
            Logger.getLogger(ManagerCoord.class.getName()).log(Level.SEVERE, null, ex);
        }
        //(polygonInt.getArea() * 1000D + (polygonInt.getArea() * 1000D * 0.217885D)) * 1000D
        return (polygonInt.getArea() * 1000D + (polygonInt.getArea() * 1000D * 0.217885D)) * 1000D;

    }

    public void onMarkerSelect(OverlaySelectEvent event) {
        try {
            marker = (Marker) event.getOverlay();
        } catch (ClassCastException e) {
            throw new ClassCastException("Erro na conversão, não é um Marker !");
        }
    }
}
